/*
 * R2XApp.java
 */
package r2x;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * The main class of the application.
 */
public class R2XApp extends SingleFrameApplication {

    private static String SETUP_FILE = "settings.xml";
    private DBManager dbManager;
    private DTDCreator dtdCreator;
    private XMLCreator xmlCreator;
    private R2XView mainWindow;
    private Document dom;
    private Element docEle;
    private int times =0;
    private String projectName;
    private String folder;

    void initializeApp() {
        setDbManager(new DBManager());
        setDtdCreator(new DTDCreator());
        setXmlCreator(new XMLCreator());
        loadSetup(SETUP_FILE);
    }

    /**
     * At startup create and show the main frame of the application.
     */
    @Override
    protected void startup() {
        initializeApp();
        try {
            mainWindow = new R2XView(this);
            show(getMainWindow());
        } catch (Exception e) {
        } finally {
            if (R2XApp.getApplication().getDbManager().closeConnection()) {
                System.out.println("Succesfully disconnected from the DB \nTo juz koniec!");
            } else {
                System.out.println("Wasn't able to disconnect from the DB \nTo juz koniec!");
            }
        }
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     */
    @Override
    protected void configureWindow(java.awt.Window root) {
    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of R2XApp
     */
    public static R2XApp getApplication() {
        return Application.getInstance(R2XApp.class);
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {
        launch(R2XApp.class, args);
    }

    /**
     * @return the dbManager
     */
    public DBManager getDbManager() {
        return dbManager;
    }

    /**
     * @param dbManager the dbManager to set
     */
    public void setDbManager(DBManager dbManager) {
        this.dbManager = dbManager;
    }

    /**
     * @return the dtdCreator
     */
    public DTDCreator getDtdCreator() {
        return dtdCreator;
    }

    /**
     * @param dtdCreator the dtdCreator to set
     */
    public void setDtdCreator(DTDCreator dtdCreator) {
        this.dtdCreator = dtdCreator;
    }

    /**
     * @return the xmlCreator
     */
    public XMLCreator getXmlCreator() {
        return xmlCreator;
    }

    /**
     * @param xmlCreator the xmlCreator to set
     */
    public void setXmlCreator(XMLCreator xmlCreator) {
        this.xmlCreator = xmlCreator;
    }

    void prepareForAnotherUsage() {
        setDtdCreator(new DTDCreator());
        setXmlCreator(new XMLCreator());
        dbManager.prepareForAnotherUsage();
        loadSetup(SETUP_FILE);
        System.gc();
    }

    void setOutputIntoFile(String _output, String _projectName) {
          NodeList tempList = docEle.getElementsByTagName("Output");
        Element el = (Element) tempList.item(0);
        el.setAttribute("path", _output);
        el.setAttribute("projectName", _projectName);
        printSetupToFile();
        loadSetup(SETUP_FILE);
    }

    private void loadSetup(String setupFile) {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            //Using factory get an instance of document builder
            DocumentBuilder db = dbf.newDocumentBuilder();

            //parse using builder to get DOM representation of the XML file
            dom = (Document) db.parse(setupFile);

            docEle = (Element) dom.getDocumentElement();
            NodeList tempList;

            //setting up output
            tempList = docEle.getElementsByTagName("Output");
            if (tempList != null && tempList.getLength() > 0) {
                Element outputEl = (Element) tempList.item(0);
                setFolder(outputEl.getAttribute("path"));
                String helper;
                if (getFolder().equals("default"))
                    helper = "";
                else
                    helper = getFolder() + "\\";
                setProjectName(outputEl.getAttribute("projectName"));

                R2XApp.getApplication().getXmlCreator().
                        setDestination(helper + getProjectName() + ".xml");
                R2XApp.getApplication().getDtdCreator().
                        setDestination(helper + getProjectName() + ".dtd");
            }

            //setting up DB
            tempList = docEle.getElementsByTagName("Database");
            if (tempList != null && tempList.getLength() > 0) {
                Element dbEl = (Element) tempList.item(0);
                String url = dbEl.getAttribute("url");
                R2XApp.getApplication().getDbManager().setUrl(url);

                String userName = dbEl.getAttribute("userName");
                R2XApp.getApplication().getDbManager().setUserName(userName);

                String dbName = dbEl.getAttribute("dbName");
                R2XApp.getApplication().getDbManager().setDbName(dbName);

                String pass = dbEl.getAttribute("password");
                R2XApp.getApplication().getDbManager().setPassword(pass);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setDBConnectionIntoFile(String _url, String _userName,
            String _dbName, String _password) {
        NodeList tempList = docEle.getElementsByTagName("Database");
        Element el = (Element) tempList.item(0);
        el.setAttribute("dbName", _dbName);
        el.setAttribute("url", _url);
        el.setAttribute("userName", _userName);
        el.setAttribute("password", _password);
        printSetupToFile();
        loadSetup(SETUP_FILE);
    }

    /**
     * @return the mainWindow
     */
    private void printSetupToFile() {

        try {
            OutputFormat format = new OutputFormat(dom);
            format.setIndenting(true);
            XMLSerializer serializer = new XMLSerializer(
                    new FileOutputStream(new File(SETUP_FILE)), format);

            serializer.serialize(dom);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public R2XView getMainWindow() {
        return mainWindow;
    }

    /**
     * @return the times
     */
    public int getTimes() {
        return times;
    }

    /**
     * @param times the times to set
     */
    public void setTimes(int times) {
        this.times = times;
    }

    /**
     * @return the projectName
     */
    public String getProjectName() {
        return projectName;
    }

    /**
     * @param projectName the projectName to set
     */
    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    /**
     * @return the folder
     */
    public String getFolder() {
        return folder;
    }

    /**
     * @param folder the folder to set
     */
    public void setFolder(String folder) {
        this.folder = folder;
    }
}
